import func_methods from '../global/func_methods'
import formula from '../global/formula'
import tooltip from '../global/tooltip'
import { isRealNum, valueIsError, error } from '../global/validate'
import { getdatabyselectionD } from '../global/getdata'
import { genarate } from '../global/format'
import { inverse } from '../function/matrix_methods'
import { getSheetIndex, getluckysheetfile, getRangetxt } from '../methods/get'
import { getObjType, ABCatNum } from '../utils/util'
import Store from '../store'
import numeral from 'numeral'

//函数功能：比较或运算
function luckysheet_compareWith() {
  //第一个参数和第三个参数，返回比较结果的布尔值或者运算值
  //formula.operatorjson; 存储运算符和比较符
  let sp = arguments[1] //操作符

  //参数一
  let data_fp = arguments[0]
  let fp
  if (getObjType(data_fp) == 'object' && data_fp.startCell != null) {
    //参数是选区
    if (sp == '&') {
      fp = func_methods.getCellDataDyadicArr(data_fp, 'text')
    } else {
      fp = func_methods.getCellDataDyadicArr(data_fp, 'number')
    }

    if (fp.length == 1 && fp[0].length == 1) {
      fp = fp[0][0]
    }
  } else {
    fp = data_fp
  }

  //参数二
  let data_tp = arguments[2]
  let tp
  if (getObjType(data_tp) == 'object' && data_tp.startCell != null) {
    //参数是选区
    if (sp == '&') {
      tp = func_methods.getCellDataDyadicArr(data_tp, 'text')
    } else {
      tp = func_methods.getCellDataDyadicArr(data_tp, 'number')
    }

    if (tp.length == 1 && tp[0].length == 1) {
      tp = tp[0][0]
    }
  } else {
    tp = data_tp
  }

  if (valueIsError(fp)) {
    return fp
  }

  if (valueIsError(tp)) {
    return tp
  }

  //参数是不规则二维数组 时 return #VALUE! 错误
  if (
    getObjType(fp) == 'array' &&
    getObjType(fp[0]) == 'array' &&
    !func_methods.isDyadicArr(fp)
  ) {
    return error.v
  }

  if (
    getObjType(tp) == 'array' &&
    getObjType(tp[0]) == 'array' &&
    !func_methods.isDyadicArr(tp)
  ) {
    return error.v
  }

  if (sp == '<>') {
    sp = '!='
  }

  if (sp == '=') {
    sp = '=='
  }

  if (fp == null && tp == null) {
    return '#INVERSE!'
  } else if (fp == '#INVERSE!') {
    fp = 0
    if (sp == '-') {
      sp = '+'
    } else if (sp == '+') {
      sp = '-'
    }
  } else if (sp == '-' && fp == null) {
    fp = 0
  } else if (sp == '/' && (tp == 0 || tp == null)) {
    return error.d
  }

  //计算result
  function booleanOperation(a, operator, b) {
    if (isRealNum(a)) {
      a = parseFloat(a)
    }

    if (isRealNum(b)) {
      b = parseFloat(b)
    }

    if (operator == '==') {
      if (a == b) {
        return true
      } else {
        return false
      }
    } else if (operator == '!=') {
      if (a != b) {
        return true
      } else {
        return false
      }
    } else if (operator == '>=') {
      if (a >= b) {
        return true
      } else {
        return false
      }
    } else if (operator == '<=') {
      if (a <= b) {
        return true
      } else {
        return false
      }
    } else if (operator == '>') {
      if (a > b) {
        return true
      } else {
        return false
      }
    } else if (operator == '<') {
      if (a < b) {
        return true
      } else {
        return false
      }
    }
  }

  //布尔值对应数字（true = 1, false = 1）
  function booleanToNum(v) {
    if (v == null) {
      return v
    }

    if (v.toString().toLowerCase() == 'true') {
      return 1
    }

    if (v.toString().toLowerCase() == 'false') {
      return 0
    }

    return v
  }

  if (sp == '*') {
    //乘
    if (getObjType(fp) == 'array' && getObjType(tp) == 'array') {
      let result = []

      if (getObjType(fp[0]) == 'array' && getObjType(tp[0]) == 'array') {
        //二维数组相乘（m*n 与 m*n 等于 m*n；m*p 与 p*n 等于 m*n；其它错误）
        if (fp.length == tp.length && fp[0].length == tp[0].length) {
          for (let m = 0; m < fp.length; m++) {
            let rowArr = []

            for (let n = 0; n < fp[m].length; n++) {
              fp[m][n] = booleanToNum(fp[m][n])
              tp[m][n] = booleanToNum(tp[m][n])

              let value
              if (isRealNum(fp[m][n]) && isRealNum(tp[m][n])) {
                value = luckysheet_calcADPMM(fp[m][n], sp, tp[m][n]) //parseFloat(fp[m][n]) * parseFloat(tp[m][n]);
              } else {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else if (fp[0].length == tp.length) {
          let rowlen = fp.length
          let collen = tp[0].length

          for (let m = 0; m < rowlen; m++) {
            let rowArr = []

            for (let n = 0; n < collen; n++) {
              let value = 0

              for (let p = 0; p < fp[0].length; p++) {
                fp[m][p] = booleanToNum(fp[m][p])
                tp[p][n] = booleanToNum(tp[p][n])

                if (isRealNum(fp[m][p]) && isRealNum(tp[p][n])) {
                  value += luckysheet_calcADPMM(fp[m][p], sp, tp[p][n]) //parseFloat(fp[m][p]) * parseFloat(tp[p][n]);
                } else {
                  value += error.v
                }
              }

              if (value.toString() == 'NaN') {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else if (fp.length == tp[0].length) {
          let rowlen = tp.length
          let collen = fp[0].length

          for (let m = 0; m < rowlen; m++) {
            let rowArr = []

            for (let n = 0; n < collen; n++) {
              let value = 0

              for (let p = 0; p < tp[0].length; p++) {
                fp[p][n] = booleanToNum(fp[p][n])
                tp[m][p] = booleanToNum(tp[m][p])

                if (isRealNum(tp[m][p]) && isRealNum(fp[p][n])) {
                  value += luckysheet_calcADPMM(fp[p][n], sp, tp[m][p]) //parseFloat(tp[m][p]) * parseFloat(fp[p][n]);
                } else {
                  value += error.v
                }
              }

              if (value.toString() == 'NaN') {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else {
          return error.na
        }
      } else if (getObjType(fp[0]) == 'array') {
        //二维数组与一维数组相乘（m*n 与 n 等于 m*n；m*1 与 n 等于 m*n；其它错误）
        if (fp[0].length == tp.length) {
          for (let m = 0; m < fp.length; m++) {
            let rowArr = []

            for (let n = 0; n < fp[m].length; n++) {
              fp[m][n] = booleanToNum(fp[m][n])
              tp[n] = booleanToNum(tp[n])

              let value
              if (isRealNum(fp[m][n]) && isRealNum(tp[n])) {
                value = luckysheet_calcADPMM(fp[m][n], sp, tp[n]) //parseFloat(fp[m][n]) * parseFloat(tp[n]);
              } else {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else if (fp[0].length == 1) {
          let rowlen = fp.length
          let collen = tp.length

          for (let m = 0; m < rowlen; m++) {
            let rowArr = []

            for (let n = 0; n < collen; n++) {
              fp[m][0] = booleanToNum(fp[m][0])
              tp[n] = booleanToNum(tp[n])

              let value
              if (isRealNum(fp[m][0]) && isRealNum(tp[n])) {
                value = luckysheet_calcADPMM(fp[m][0], sp, tp[n]) // parseFloat(fp[m][0]) * parseFloat(tp[n]);
              } else {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else {
          return error.na
        }
      } else if (getObjType(tp[0]) == 'array') {
        //二维数组与一维数组相乘（m*n 与 n 等于 m*n；m*1 与 n 等于 m*n；其它错误）
        if (tp[0].length == fp.length) {
          for (let m = 0; m < tp.length; m++) {
            let rowArr = []

            for (let n = 0; n < tp[m].length; n++) {
              fp[n] = booleanToNum(fp[n])
              tp[m][n] = booleanToNum(tp[m][n])

              let value
              if (isRealNum(fp[n]) && isRealNum(tp[m][n])) {
                value = luckysheet_calcADPMM(fp[n], sp, tp[m][n]) // parseFloat(fp[n]) * parseFloat(tp[m][n]);
              } else {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else if (tp[0].length == 1) {
          let rowlen = tp.length
          let collen = fp.length

          for (let m = 0; m < rowlen; m++) {
            let rowArr = []

            for (let n = 0; n < collen; n++) {
              fp[n] = booleanToNum(fp[n])
              tp[m][0] = booleanToNum(tp[m][0])

              let value
              if (isRealNum(fp[n]) && isRealNum(tp[m][0])) {
                value = luckysheet_calcADPMM(fp[n], sp, tp[m][0]) //parseFloat(fp[n]) * parseFloat(tp[m][0]);
              } else {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else {
          return error.na
        }
      } else {
        //一维数组与一维数组相乘时，数组大小不一样是错误
        if (fp.length != tp.length) {
          return error.na
        }

        for (let n = 0; n < fp.length; n++) {
          fp[n] = booleanToNum(fp[n])
          tp[n] = booleanToNum(tp[n])

          let value
          if (isRealNum(fp[n]) && isRealNum(tp[n])) {
            value = luckysheet_calcADPMM(fp[n], sp, tp[n]) // parseFloat(fp[n]) * parseFloat(tp[n]);
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else if (getObjType(fp) == 'array') {
      tp = booleanToNum(tp)

      let result = []

      if (getObjType(fp[0]) == 'array') {
        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            fp[m][n] = booleanToNum(fp[m][n])

            let value
            if (isRealNum(fp[m][n]) && isRealNum(tp)) {
              value = luckysheet_calcADPMM(fp[m][n], sp, tp) // parseFloat(fp[m][n]) * parseFloat(tp);
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < fp.length; n++) {
          fp[n] = booleanToNum(fp[n])

          let value
          if (isRealNum(fp[n]) && isRealNum(tp)) {
            value = luckysheet_calcADPMM(fp[n], sp, tp) // parseFloat(fp[n]) * parseFloat(tp);
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else if (getObjType(tp) == 'array') {
      fp = booleanToNum(fp)

      let result = []

      if (getObjType(tp[0]) == 'array') {
        for (let m = 0; m < tp.length; m++) {
          let rowArr = []

          for (let n = 0; n < tp[m].length; n++) {
            tp[m][n] = booleanToNum(tp[m][n])

            let value
            if (isRealNum(fp) && isRealNum(tp[m][n])) {
              value = luckysheet_calcADPMM(fp, sp, tp[m][n]) // parseFloat(fp) * parseFloat(tp[m][n]);
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < tp.length; n++) {
          tp[n] = booleanToNum(tp[n])

          let value
          if (isRealNum(fp) && isRealNum(tp[n])) {
            value = luckysheet_calcADPMM(fp, sp, tp[n]) //parseFloat(fp) * parseFloat(tp[n]);
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else {
      fp = booleanToNum(fp)
      tp = booleanToNum(tp)

      let result
      if (isRealNum(fp) && isRealNum(tp)) {
        result = luckysheet_calcADPMM(fp, sp, tp) //parseFloat(fp) * parseFloat(tp);
      } else {
        result = error.v
      }

      return result
    }
  } else if (sp == '/') {
    //除
    if (getObjType(fp) == 'array' && getObjType(tp) == 'array') {
      let result = []

      if (getObjType(fp[0]) == 'array' && getObjType(tp[0]) == 'array') {
        //二维数组相除（m*n 与 m*n 等于 m*n；m*p 与 p*n 等于 m*n；其它错误）
        if (fp.length == tp.length && fp[0].length == tp[0].length) {
          for (let m = 0; m < fp.length; m++) {
            let rowArr = []

            for (let n = 0; n < fp[m].length; n++) {
              fp[m][n] = booleanToNum(fp[m][n])
              tp[m][n] = booleanToNum(tp[m][n])

              let value
              if (isRealNum(fp[m][n]) && isRealNum(tp[m][n])) {
                if (parseFloat(tp[m][n]) == 0) {
                  value = error.d
                } else {
                  value = luckysheet_calcADPMM(fp[m][n], sp, tp[m][n]) // parseFloat(fp[m][n]) / parseFloat(tp[m][n]);
                }
              } else {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else if (fp[0].length == tp.length) {
          let tp_inverse = inverse(tp)

          let rowlen = fp.length
          let collen = tp_inverse[0].length

          for (let m = 0; m < rowlen; m++) {
            let rowArr = []

            for (let n = 0; n < collen; n++) {
              let value = 0

              for (let p = 0; p < fp[0].length; p++) {
                fp[m][p] = booleanToNum(fp[m][p])
                tp_inverse[p][n] = booleanToNum(tp_inverse[p][n])

                if (isRealNum(fp[m][p]) && isRealNum(tp_inverse[p][n])) {
                  value += luckysheet_calcADPMM(fp[m][p], '*', tp_inverse[p][n]) // parseFloat(fp[m][p]) * parseFloat(tp_inverse[p][n]);
                } else {
                  value += error.v
                }
              }

              if (value.toString() == 'NaN') {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else {
          return error.na
        }
      } else if (getObjType(fp[0]) == 'array') {
        //二维数组与一维数组相除（m*n 与 n 等于 m*n；m*1 与 n 等于 m*n；其它错误）
        if (fp[0].length == tp.length) {
          for (let m = 0; m < fp.length; m++) {
            let rowArr = []

            for (let n = 0; n < fp[m].length; n++) {
              fp[m][n] = booleanToNum(fp[m][n])
              tp[n] = booleanToNum(tp[n])

              let value
              if (isRealNum(fp[m][n]) && isRealNum(tp[n])) {
                if (parseFloat(tp[n]) == 0) {
                  value = error.d
                } else {
                  value = luckysheet_calcADPMM(fp[m][n], sp, tp[n]) // parseFloat(fp[m][n]) / parseFloat(tp[n]);
                }
              } else {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else if (fp[0].length == 1) {
          let rowlen = fp.length
          let collen = tp.length

          for (let m = 0; m < rowlen; m++) {
            let rowArr = []

            for (let n = 0; n < collen; n++) {
              fp[m][0] = booleanToNum(fp[m][0])
              tp[n] = booleanToNum(tp[n])

              let value
              if (isRealNum(fp[m][0]) && isRealNum(tp[n])) {
                if (parseFloat(tp[n]) == 0) {
                  value = error.d
                } else {
                  value = luckysheet_calcADPMM(fp[m][0], sp, tp[n]) // parseFloat(fp[m][0]) / parseFloat(tp[n]);
                }
              } else {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else {
          return error.na
        }
      } else if (getObjType(tp[0]) == 'array') {
        //二维数组与一维数组相除（m*n 与 n 等于 m*n；m*1 与 n 等于 m*n；其它错误）
        if (tp[0].length == fp.length) {
          for (let m = 0; m < tp.length; m++) {
            let rowArr = []

            for (let n = 0; n < tp[m].length; n++) {
              fp[n] = booleanToNum(fp[n])
              tp[m][n] = booleanToNum(tp[m][n])

              let value
              if (isRealNum(fp[n]) && isRealNum(tp[m][n])) {
                if (parseFloat(tp[m][n]) == 0) {
                  value = error.d
                } else {
                  value = luckysheet_calcADPMM(fp[n], sp, tp[m][n]) //parseFloat(fp[n]) / parseFloat(tp[m][n]);
                }
              } else {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else if (tp[0].length == 1) {
          let rowlen = tp.length
          let collen = fp.length

          for (let m = 0; m < rowlen; m++) {
            let rowArr = []

            for (let n = 0; n < collen; n++) {
              fp[n] = booleanToNum(fp[n])
              tp[m][0] = booleanToNum(tp[m][0])

              let value
              if (isRealNum(fp[n]) && isRealNum(tp[m][0])) {
                if (parseFloat(tp[m][0]) == 0) {
                  value = error.d
                } else {
                  value = luckysheet_calcADPMM(fp[n], sp, tp[m][0]) //parseFloat(fp[n]) / parseFloat(tp[m][0]);
                }
              } else {
                value = error.v
              }

              rowArr.push(value)
            }

            result.push(rowArr)
          }
        } else {
          return error.na
        }
      } else {
        //一维数组与一维数组相除时，数组大小不一样是错误
        if (fp.length != tp.length) {
          return error.na
        }

        for (let n = 0; n < fp.length; n++) {
          fp[n] = booleanToNum(fp[n])
          tp[n] = booleanToNum(tp[n])

          let value
          if (isRealNum(fp[n]) && isRealNum(tp[n])) {
            if (parseFloat(tp[n]) == 0) {
              value = error.d
            } else {
              value = luckysheet_calcADPMM(fp[n], sp, tp[n]) //parseFloat(fp[n]) / parseFloat(tp[n]);
            }
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else if (getObjType(fp) == 'array') {
      tp = booleanToNum(tp)

      let result = []

      if (getObjType(fp[0]) == 'array') {
        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            fp[m][n] = booleanToNum(fp[m][n])

            let value
            if (isRealNum(fp[m][n]) && isRealNum(tp)) {
              if (parseFloat(tp) == 0) {
                value = error.d
              } else {
                value = luckysheet_calcADPMM(fp[m][n], sp, tp) //parseFloat(fp[m][n]) / parseFloat(tp);
              }
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < fp.length; n++) {
          fp[n] = booleanToNum(fp[n])

          let value
          if (isRealNum(fp[n]) && isRealNum(tp)) {
            if (parseFloat(tp) == 0) {
              value = error.d
            } else {
              value = luckysheet_calcADPMM(fp[n], sp, tp) //parseFloat(fp[n]) / parseFloat(tp);
            }
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else if (getObjType(tp) == 'array') {
      fp = booleanToNum(fp)

      let result = []

      if (getObjType(tp[0]) == 'array') {
        for (let m = 0; m < tp.length; m++) {
          let rowArr = []

          for (let n = 0; n < tp[m].length; n++) {
            tp[m][n] = booleanToNum(tp[m][n])

            let value
            if (isRealNum(fp) && isRealNum(tp[m][n])) {
              if (parseFloat(tp[m][n]) == 0) {
                value = error.d
              } else {
                value = luckysheet_calcADPMM(fp, sp, tp[m][n]) //parseFloat(fp) / parseFloat(tp[m][n]);
              }
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < tp.length; n++) {
          tp[n] = booleanToNum(tp[n])

          let value
          if (isRealNum(fp) && isRealNum(tp[n])) {
            if (parseFloat(tp[n]) == 0) {
              value = error.d
            } else {
              value = luckysheet_calcADPMM(fp, sp, tp[n]) //parseFloat(fp) / parseFloat(tp[n]);
            }
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else {
      fp = booleanToNum(fp)
      tp = booleanToNum(tp)

      let result
      if (isRealNum(fp) && isRealNum(tp)) {
        if (parseFloat(tp) == 0) {
          result = error.d
        } else {
          result = luckysheet_calcADPMM(fp, sp, tp) //parseFloat(fp) / parseFloat(tp);
        }
      } else {
        result = error.v
      }

      return result
    }
  } else if (sp == '+' || sp == '-' || sp == '%') {
    //加 减 取余
    if (getObjType(fp) == 'array' && getObjType(tp) == 'array') {
      let result = []

      if (getObjType(fp[0]) == 'array' && getObjType(tp[0]) == 'array') {
        if (fp.length != tp.length && fp[0].length != tp[0].length) {
          return error.na
        }

        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            fp[m][n] = booleanToNum(fp[m][n])
            tp[m][n] = booleanToNum(tp[m][n])

            let value
            if (isRealNum(fp[m][n]) && isRealNum(tp[m][n])) {
              if (sp == '%' && parseFloat(tp[m][n]) == 0) {
                value = error.d
              } else {
                value = luckysheet_calcADPMM(fp[m][n], sp, tp[m][n]) // eval(parseFloat(fp[m][n]) + sp + parseFloat(tp[m][n]));
              }
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else if (getObjType(fp[0]) == 'array') {
        if (fp[0].length != tp.length) {
          return error.na
        }

        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            fp[m][n] = booleanToNum(fp[m][n])
            tp[n] = booleanToNum(tp[n])

            let value
            if (isRealNum(fp[m][n]) && isRealNum(tp[n])) {
              if (sp == '%' && parseFloat(tp[n]) == 0) {
                value = error.d
              } else {
                value = luckysheet_calcADPMM(fp[m][n], sp, tp[n]) //eval(parseFloat(fp[m][n]) + sp + parseFloat(tp[n]));
              }
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else if (getObjType(tp[0]) == 'array') {
        if (tp[0].length != fp.length) {
          return error.na
        }

        for (let m = 0; m < tp.length; m++) {
          let rowArr = []

          for (let n = 0; n < tp[m].length; n++) {
            fp[n] = booleanToNum(fp[n])
            tp[m][n] = booleanToNum(tp[m][n])

            let value
            if (isRealNum(fp[n]) && isRealNum(tp[m][n])) {
              if (sp == '%' && parseFloat(tp[m][n]) == 0) {
                value = error.d
              } else {
                value = luckysheet_calcADPMM(fp[n], sp, tp[m][n]) //eval(parseFloat(fp[n]) + sp + parseFloat(tp[m][n]));
              }
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        if (fp.length != tp.length) {
          return error.na
        }

        for (let n = 0; n < fp.length; n++) {
          fp[n] = booleanToNum(fp[n])
          tp[n] = booleanToNum(tp[n])

          let value
          if (isRealNum(fp[n]) && isRealNum(tp[n])) {
            if (sp == '%' && parseFloat(tp[n]) == 0) {
              value = error.d
            } else {
              value = luckysheet_calcADPMM(fp[n], sp, tp[n]) //eval(parseFloat(fp[n]) + sp + "(" + parseFloat(tp[n]) + ")" );
            }
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else if (getObjType(fp) == 'array') {
      tp = booleanToNum(tp)

      let result = []

      if (getObjType(fp[0]) == 'array') {
        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            fp[m][n] = booleanToNum(fp[m][n])

            let value
            if (isRealNum(fp[m][n]) && isRealNum(tp)) {
              if (sp == '%' && parseFloat(tp) == 0) {
                value = error.d
              } else {
                value = luckysheet_calcADPMM(fp[m][n], sp, tp) //eval(parseFloat(fp[m][n]) + sp + parseFloat(tp));
              }
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < fp.length; n++) {
          fp[n] = booleanToNum(fp[n])

          let value
          if (isRealNum(fp[n]) && isRealNum(tp)) {
            if (sp == '%' && parseFloat(tp) == 0) {
              value = error.d
            } else {
              value = luckysheet_calcADPMM(fp[n], sp, tp) //eval(parseFloat(fp[n]) + sp + parseFloat(tp));
            }
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else if (getObjType(tp) == 'array') {
      fp = booleanToNum(fp)

      let result = []

      if (getObjType(tp[0]) == 'array') {
        for (let m = 0; m < tp.length; m++) {
          let rowArr = []

          for (let n = 0; n < tp[m].length; n++) {
            tp[m][n] = booleanToNum(tp[m][n])

            let value
            if (isRealNum(fp) && isRealNum(tp[m][n])) {
              if (sp == '%' && parseFloat(tp[m][n]) == 0) {
                value = error.d
              } else {
                value = luckysheet_calcADPMM(fp, sp, tp[m][n]) //eval(parseFloat(fp) + sp + parseFloat(tp[m][n]));
              }
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < tp.length; n++) {
          tp[n] = booleanToNum(tp[n])

          let value
          if (isRealNum(fp) && isRealNum(tp[n])) {
            if (sp == '%' && parseFloat(tp[n]) == 0) {
              value = error.d
            } else {
              value = luckysheet_calcADPMM(fp, sp, tp[n]) //eval(parseFloat(fp) + sp + parseFloat(tp[n]));
            }
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else {
      fp = booleanToNum(fp)
      tp = booleanToNum(tp)

      let result
      if (isRealNum(fp) && isRealNum(tp)) {
        if (sp == '%' && parseFloat(tp) == 0) {
          result = error.d
        } else {
          result = luckysheet_calcADPMM(fp, sp, tp) //eval(parseFloat(fp) + sp + "(" + parseFloat(tp) + ")");
        }
      } else {
        result = error.v
      }

      return result
    }
  } else if (
    sp == '==' ||
    sp == '!=' ||
    sp == '>=' ||
    sp == '<=' ||
    sp == '>' ||
    sp == '<'
  ) {
    //比较运算符
    if (getObjType(fp) == 'array' && getObjType(tp) == 'array') {
      let result = []

      if (getObjType(fp[0]) == 'array' && getObjType(tp[0]) == 'array') {
        if (fp.length != tp.length && fp[0].length != tp[0].length) {
          return error.na
        }

        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            let value = booleanOperation(fp[m][n], sp, tp[m][n])
            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else if (getObjType(fp[0]) == 'array') {
        if (fp[0].length != tp.length) {
          return error.na
        }

        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            let value = booleanOperation(fp[m][n], sp, tp[n])
            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else if (getObjType(tp[0]) == 'array') {
        if (tp[0].length != fp.length) {
          return error.na
        }

        for (let m = 0; m < tp.length; m++) {
          let rowArr = []

          for (let n = 0; n < tp[m].length; n++) {
            let value = booleanOperation(fp[n], sp, tp[m][n])
            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        if (fp.length != tp.length) {
          return error.na
        }

        for (let n = 0; n < fp.length; n++) {
          let value = booleanOperation(fp[n], sp, tp[n])
          result.push(value)
        }
      }

      return result
    } else if (getObjType(fp) == 'array') {
      let result = []

      if (getObjType(fp[0]) == 'array') {
        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            let value = booleanOperation(fp[m][n], sp, tp)
            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < fp.length; n++) {
          let value = booleanOperation(fp[n], sp, tp)
          result.push(value)
        }
      }

      return result
    } else if (getObjType(tp) == 'array') {
      let result = []

      if (getObjType(tp[0]) == 'array') {
        for (let m = 0; m < tp.length; m++) {
          let rowArr = []

          for (let n = 0; n < tp[m].length; n++) {
            let value = booleanOperation(fp, sp, tp[m][n])
            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < tp.length; n++) {
          let value = booleanOperation(fp, sp, tp[n])
          result.push(value)
        }
      }

      return result
    } else {
      return booleanOperation(fp, sp, tp)
    }
  } else if (sp == '&') {
    //连接符
    if (getObjType(fp) == 'array' && getObjType(tp) == 'array') {
      let result = []

      if (getObjType(fp[0]) == 'array' && getObjType(tp[0]) == 'array') {
        if (fp.length != tp.length && fp[0].length != tp[0].length) {
          return error.na
        }

        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            rowArr.push(fp[m][n] + '' + tp[m][n])
          }

          result.push(rowArr)
        }
      } else if (getObjType(fp[0]) == 'array') {
        if (fp[0].length != tp.length) {
          return error.na
        }

        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            rowArr.push(fp[m][n] + '' + tp[n])
          }

          result.push(rowArr)
        }
      } else if (getObjType(tp[0]) == 'array') {
        if (tp[0].length != fp.length) {
          return error.na
        }

        for (let m = 0; m < tp.length; m++) {
          let rowArr = []

          for (let n = 0; n < tp[m].length; n++) {
            rowArr.push(fp[n] + '' + tp[m][n])
          }

          result.push(rowArr)
        }
      } else {
        if (fp.length != tp.length) {
          return error.na
        }

        for (let n = 0; n < fp.length; n++) {
          result.push(fp[n] + '' + tp[n])
        }
      }

      return result
    } else if (getObjType(fp) == 'array') {
      let result = []

      if (getObjType(fp[0]) == 'array') {
        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            rowArr.push(fp[m][n] + '' + tp)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < fp.length; n++) {
          result.push(fp[n] + '' + tp)
        }
      }

      return result
    } else if (getObjType(tp) == 'array') {
      let result = []

      if (getObjType(tp[0]) == 'array') {
        for (let m = 0; m < tp.length; m++) {
          let rowArr = []

          for (let n = 0; n < tp[m].length; n++) {
            rowArr.push(fp + '' + tp[m][n])
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < tp.length; n++) {
          result.push(fp + '' + tp[n])
        }
      }

      return result
    } else {
      return fp + '' + tp
    }
  } else if (sp == '^') {
    //幂
    if (getObjType(fp) == 'array' && getObjType(tp) == 'array') {
      let result = []

      if (getObjType(fp[0]) == 'array' && getObjType(tp[0]) == 'array') {
        if (fp.length != tp.length && fp[0].length != tp[0].length) {
          return error.na
        }

        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            fp[m][n] = booleanToNum(fp[m][n])
            tp[m][n] = booleanToNum(tp[m][n])

            let value
            if (isRealNum(fp[m][n]) && isRealNum(tp[m][n])) {
              value = Math.pow(parseFloat(fp[m][n]), parseFloat(tp[m][n]))
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else if (getObjType(fp[0]) == 'array') {
        if (fp[0].length != tp.length) {
          return error.na
        }

        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            fp[m][n] = booleanToNum(fp[m][n])
            tp[n] = booleanToNum(tp[n])

            let value
            if (isRealNum(fp[m][n]) && isRealNum(tp[n])) {
              value = Math.pow(parseFloat(fp[m][n]), parseFloat(tp[n]))
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else if (getObjType(tp[0]) == 'array') {
        if (tp[0].length != fp.length) {
          return error.na
        }

        for (let m = 0; m < tp.length; m++) {
          let rowArr = []

          for (let n = 0; n < tp[m].length; n++) {
            fp[n] = booleanToNum(fp[n])
            tp[m][n] = booleanToNum(tp[m][n])

            let value
            if (isRealNum(fp[n]) && isRealNum(tp[m][n])) {
              value = Math.pow(parseFloat(fp[n]), parseFloat(tp[m][n]))
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        if (fp.length != tp.length) {
          return error.na
        }

        for (let n = 0; n < fp.length; n++) {
          fp[n] = booleanToNum(fp[n])
          tp[n] = booleanToNum(tp[n])

          let value
          if (isRealNum(fp[n]) && isRealNum(tp[n])) {
            value = Math.pow(parseFloat(fp[n]), parseFloat(tp[n]))
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else if (getObjType(fp) == 'array') {
      tp = booleanToNum(tp)

      let result = []

      if (getObjType(fp[0]) == 'array') {
        for (let m = 0; m < fp.length; m++) {
          let rowArr = []

          for (let n = 0; n < fp[m].length; n++) {
            fp[m][n] = booleanToNum(fp[m][n])

            let value
            if (isRealNum(fp[m][n]) && isRealNum(tp)) {
              value = Math.pow(parseFloat(fp[m][n]), parseFloat(tp))
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < fp.length; n++) {
          fp[n] = booleanToNum(fp[n])

          let value
          if (isRealNum(fp[n]) && isRealNum(tp)) {
            value = Math.pow(parseFloat(fp[n]), parseFloat(tp))
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else if (getObjType(tp) == 'array') {
      fp = booleanToNum(fp)

      let result = []

      if (getObjType(tp[0]) == 'array') {
        for (let m = 0; m < tp.length; m++) {
          let rowArr = []

          for (let n = 0; n < tp[m].length; n++) {
            tp[m][n] = booleanToNum(tp[m][n])

            let value
            if (isRealNum(fp) && isRealNum(tp[m][n])) {
              value = Math.pow(parseFloat(fp), parseFloat(tp[m][n]))
            } else {
              value = error.v
            }

            rowArr.push(value)
          }

          result.push(rowArr)
        }
      } else {
        for (let n = 0; n < tp.length; n++) {
          tp[n] = booleanToNum(tp[n])

          let value
          if (isRealNum(fp) && isRealNum(tp[n])) {
            value = Math.pow(parseFloat(fp), parseFloat(tp[n]))
          } else {
            value = error.v
          }

          result.push(value)
        }
      }

      return result
    } else {
      fp = booleanToNum(fp)
      tp = booleanToNum(tp)

      let result
      if (isRealNum(fp) && isRealNum(tp)) {
        result = Math.pow(parseFloat(fp), parseFloat(tp))
      } else {
        result = error.v
      }

      return result
    }
  }
}

//解析 公式中{1,2,3;2,3,4} 为数组[[1,2,3],[2,3,4]]
function luckysheet_getarraydata() {
  let fp = arguments[0]

  fp = fp
    .replace('{', '')
    .replace('}', '')
    .replace(/\"/g, '')

  let arr = []

  if (fp.indexOf(';') > -1) {
    arr = fp.split(';')

    for (let i = 0; i < arr.length; i++) {
      arr[i] = arr[i].split(',')
    }
  } else {
    arr = fp.split(',')
  }

  return arr
}

function luckysheet_calcADPMM(fp, sp, tp) {
  let value
  if (sp == '+') {
    value = numeral(fp)
      .add(tp)
      .value()
  } else if (sp == '-') {
    value = numeral(fp)
      .subtract(tp)
      .value()
  } else if (sp == '%') {
    value = new Function(
      'return ' + parseFloat(fp) + sp + '(' + parseFloat(tp) + ')'
    )()
  } else if (sp == '/') {
    value = numeral(fp)
      .divide(tp)
      .value()
  } else if (sp == '*') {
    value = numeral(fp)
      .multiply(tp)
      .value()
  }
  return value
}

function luckysheet_getcelldata(txt) {
  if (window.luckysheet_getcelldata_cache == null) {
    window.luckysheet_getcelldata_cache = {}
  }

  if (txt in window.luckysheet_getcelldata_cache) {
    return window.luckysheet_getcelldata_cache[txt]
  }

  let luckysheetfile = getluckysheetfile()
  let val = txt.split('!')
  let sheettxt = '',
    rangetxt = '',
    sheetIndex = -1,
    sheetdata = null

  if (val.length > 1) {
    sheettxt = val[0].replace(/''/g, "'")
    rangetxt = val[1]

    if (
      sheettxt.substr(0, 1) == "'" &&
      sheettxt.substr(sheettxt.length - 1, 1) == "'"
    ) {
      sheettxt = sheettxt.substring(1, sheettxt.length - 1)
    }

    for (let i in luckysheetfile) {
      if (sheettxt == luckysheetfile[i].name) {
        sheetIndex = luckysheetfile[i].index
        sheetdata = luckysheetfile[i].data
        break
      }
    }

    if (sheetIndex == -1) {
      sheetIndex = 0
    }
  } else {
    let index = getSheetIndex(Store.calculateSheetIndex)
    sheettxt = luckysheetfile[index].name
    sheetIndex = luckysheetfile[index].index
    // sheetdata = Store.flowdata;
    sheetdata = luckysheetfile[index].data
    rangetxt = val[0]

    // 取消execFunctionGroupData，改用execFunctionGlobalData
    // if (formula.execFunctionGroupData != null) {
    //     sheetdata = formula.execFunctionGroupData;
    // }
  }

  if (rangetxt.indexOf(':') == -1) {
    let row = parseInt(rangetxt.replace(/[^0-9]/g, '')) - 1
    let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, ''))

    if (!isNaN(row) && !isNaN(col)) {
      let ret = getdatabyselectionD(sheetdata, {
        row: [row, row],
        column: [col, col],
      })[0][0]

      if (formula.execFunctionGlobalData != null) {
        let ef =
          formula.execFunctionGlobalData[row + '_' + col + '_' + sheetIndex]
        if (ef != null) {
          ret = ef
        }
      }

      //范围的长宽
      let rowl = 1
      let coll = 1
      let retAll = {
        sheetName: sheettxt,
        startCell: rangetxt,
        rowl: rowl,
        coll: coll,
        data: ret,
      }

      window.luckysheet_getcelldata_cache[txt] = retAll

      return retAll
    } else {
      return []
    }
  } else {
    rangetxt = rangetxt.split(':')
    let row = [],
      col = []
    row[0] = parseInt(rangetxt[0].replace(/[^0-9]/g, '')) - 1
    row[1] = parseInt(rangetxt[1].replace(/[^0-9]/g, '')) - 1

    if (isNaN(row[0])) {
      row[0] = 0
    }

    if (isNaN(row[1])) {
      row[1] = sheetdata.length - 1
    }

    if (row[0] > row[1]) {
      tooltip.info('选择失败', '输入范围错误！')
      return []
    }

    col[0] = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, ''))
    col[1] = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, ''))

    if (isNaN(col[0])) {
      col[0] = 0
    }

    if (isNaN(col[1])) {
      col[1] = sheetdata[0].length - 1
    }

    if (col[0] > col[1]) {
      tooltip.info('选择失败', '输入范围错误！')
      return []
    }

    let ret = getdatabyselectionD(sheetdata, {
      row: row,
      column: col,
    })

    if (formula.execFunctionGlobalData != null) {
      for (let r = row[0]; r <= row[1]; r++) {
        for (let c = col[0]; c <= col[1]; c++) {
          let ef =
            formula.execFunctionGlobalData[r + '_' + c + '_' + sheetIndex]
          if (ef != null) {
            ret[r - row[0]][c - col[0]] = ef
          }
        }
      }
    }

    //范围的长宽
    let rowl = row[1] - row[0] + 1
    let coll = col[1] - col[0] + 1
    let retAll = {
      sheetName: sheettxt,
      startCell: rangetxt[0],
      rowl: rowl,
      coll: coll,
      data: ret,
    }

    window.luckysheet_getcelldata_cache[txt] = retAll

    return retAll
  }
}

//解析单个取得的值，有字符串，数字，引用单元格或者函数
function luckysheet_parseData(value) {
  if (typeof value === 'object') {
    if (value == null) {
      return ''
    } else if (Array.isArray(value)) {
      //函数返回的带期望格式的数组，可提取格式
      let v = genarate(value[0])
      return v[2]
    } else {
      //getcelldat引用单元格对象，带有格式
      if (Array.isArray(value.data)) {
        //单元格区域
        return error.v
      } else {
        //单个单元格
        if (value.data.v === undefined) {
          return ''
        } else {
          return value.data.v
        }
      }
    }
  } else if (!formula.isCompareOperator(value).flag) {
    let v = genarate(value)
    return v[2]
  } else if (typeof value === 'string' || typeof value === 'number') {
    return value
  }

  return error.v
}

function luckysheet_getValue() {
  //解析获取函数参数，无格式，且可包含带操作符的">5"
  //数据类型：1.手动输入或函数返回的字符串，普通字符串或数字直接取值，特殊格式需转化 如："2019-1-1"（特殊格式转化为数字）、">5"或数字
  //2.引用单元格对象，取得二维数组或单个的v 如：A1
  //3.函数返回的带期望格式的数组，取得第一个参数，转化为数字 如：["2019-1-1",true]
  let args = arguments[0]

  for (let i = 0; i < args.length; i++) {
    let value = args[i]

    if (typeof value === 'object') {
      if (value == null) {
        value = ''
      } else if (Array.isArray(value)) {
        //函数返回的带期望格式的数组，可提取格式
        let v = genarate(value[0])
        value = v[2]
      } else {
        //getcelldat引用单元格对象，带有格式
        if (Array.isArray(value.data)) {
          //单元格区域
          value = value.data
        } else {
          //单个单元格
          if (value.data.v === undefined) {
            //空白单元格
            value = ''
          } else {
            value = value.data.v
          }
        }
      }
    } else if (!formula.isCompareOperator(value).flag) {
      let v = genarate(value)
      value = v[2]
    }

    args[i] = value
  }
}

function luckysheet_indirect_check() {
  let cellTxt = arguments[0]
  if (cellTxt == null || cellTxt.length == 0) {
    return null
  }
  return cellTxt
}

function luckysheet_indirect_check_return(txt) {
  return txt
}

function luckysheet_offset_check() {
  if (
    !(getObjType(arguments[0]) == 'object' && arguments[0].startCell != null)
  ) {
    return formula.error.v
  }

  var reference = arguments[0].startCell

  //要偏移的行数
  var rows = func_methods.getFirstValue(arguments[1])
  if (valueIsError(rows)) {
    return rows
  }

  if (!isRealNum(rows)) {
    return formula.error.v
  }

  rows = parseInt(rows)

  //要偏移的列数
  var cols = func_methods.getFirstValue(arguments[2])
  if (valueIsError(cols)) {
    return cols
  }

  if (!isRealNum(cols)) {
    return formula.error.v
  }

  cols = parseInt(cols)

  //要从偏移目标开始返回的范围的高度
  var height = arguments[0].rowl
  if (arguments.length >= 4) {
    height = func_methods.getFirstValue(arguments[3])
    if (valueIsError(height)) {
      return height
    }

    if (!isRealNum(height)) {
      return formula.error.v
    }

    height = parseInt(height)
  }

  //要从偏移目标开始返回的范围的宽度
  var width = arguments[0].coll
  if (arguments.length == 5) {
    width = func_methods.getFirstValue(arguments[4])
    if (valueIsError(width)) {
      return width
    }

    if (!isRealNum(width)) {
      return formula.error.v
    }

    width = parseInt(width)
  }

  if (height < 1 || width < 1) {
    return formula.error.r
  }

  //计算
  var cellrange = formula.getcellrange(reference)
  var cellRow0 = cellrange['row'][0]
  var cellCol0 = cellrange['column'][0]

  cellRow0 += rows
  cellCol0 += cols

  var cellRow1 = cellRow0 + height - 1
  var cellCol1 = cellCol0 + width - 1

  if (
    cellRow0 < 0 ||
    cellRow1 >= Store.flowdata.length ||
    cellCol0 < 0 ||
    cellCol1 >= Store.flowdata[0].length
  ) {
    return formula.error.r
  }

  return getRangetxt(Store.calculateSheetIndex, {
    row: [cellRow0, cellRow1],
    column: [cellCol0, cellCol1],
  })
}

function luckysheet_getSpecialReference(isCellFirst, param1, param2) {
  let functionRange, rangeTxt
  if (isCellFirst) {
    rangeTxt = param1
    functionRange = param2
  } else {
    functionRange = param1
    rangeTxt = param2
  }

  if (functionRange.startCell.indexOf(':') > -1 || rangeTxt.indexOf(':') > -1) {
    return error.v
  }

  if (isCellFirst) {
    return luckysheet_getcelldata(rangeTxt + ':' + functionRange.startCell)
  } else {
    let rangeT = rangeTxt,
      sheetName = ''
    if (rangeTxt.indexOf('!') > -1) {
      let rangetxtArr = rangeTxt.split('!')
      sheetName = rangetxtArr[0] + '!'
      rangeT = rangetxtArr[1]
    }
    return luckysheet_getcelldata(
      sheetName + functionRange.startCell + ':' + rangeT
    )
  }
}

export {
  luckysheet_compareWith,
  luckysheet_getarraydata,
  luckysheet_getcelldata,
  luckysheet_parseData,
  luckysheet_getValue,
  luckysheet_indirect_check,
  luckysheet_indirect_check_return,
  luckysheet_offset_check,
  luckysheet_calcADPMM,
  luckysheet_getSpecialReference,
}
